package com.wsc.controller;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class FIControle {
	String index_ip,index_user,frontier_ip,frontier_user,FIControlelogfile;
	int frontier_port,index_port;//specify default port values of frontier and index servers here
	ControllerClient cclient;

		
	public void shutdownFrontier() throws Exception{
		cclient = new ControllerClient();
		cclient.sendRequest(frontier_ip, frontier_port, "shutdown");
		//make sure that frontier is shutdown here
	}
	
	public void shutdownIndex() throws Exception{
		cclient = new ControllerClient();
		cclient.sendRequest(index_ip, index_port, "shutdown");
		//make sure that index is shutdown here
	}
	
	public void logCreation() throws IOException{
		FIControlelogfile = Logger.logfile("FIStartup");
		Logger.writeLog(FIControlelogfile,"FIContorllerlogfilecreation is done\n");
	}	
	
	public boolean isFrontierServerup() throws IOException, Exception{//checks weather frontier server is up or not
		Logger.writeLog(FIControlelogfile,"checking Frontier server is up or not \n");
		int statuscode,attempt=1;
		ControllerClient cclient;
		while(true){
			cclient = new ControllerClient();
			cclient.sendRequest(frontier_ip,frontier_port,"heartbeat");
			statuscode = cclient.getStatuscode();
			if(statuscode != 200){
				if(attempt == 6){
					Logger.writeLog(FIControlelogfile,"Frontier is not responding. check fisstartup logfile for furtherdetails.... number of attempts made :\n"+(attempt++));
					Logger.writeLog(FIControlelogfile,"Controller is going to shutdown.\n");
					return false;
				}
				Logger.writeLog(FIControlelogfile,"Frontier is not responding. attempt number :\n"+(attempt++));
				Thread.sleep(2000);
			}
			else{
				Logger.writeLog(FIControlelogfile,"Frontier is ok. it is responding to the heartbeat\n");
				return true;
			}
		}
	}
	
	public boolean isIndexServerup() throws IOException, Exception{//checks weather index server is up or not
		Logger.writeLog(FIControlelogfile,"checking index server is up or not \n");
		int statuscode,attempt=1;
		ControllerClient cclient;
		while(true){
			cclient = new ControllerClient();
			cclient.sendRequest(index_ip,index_port,"heartbeat");
			
			statuscode = cclient.getStatuscode();
			
			if(statuscode != 200){
				if(attempt == 6){
					Logger.writeLog(FIControlelogfile,"index is not responding. check fisstartup logfile for furtherdetails.... number of attempts made :\n"+(attempt++));
					Logger.writeLog(FIControlelogfile,"Controller is going to shutdown.\n");
					return false;
				}
				Logger.writeLog(FIControlelogfile,"index is not responding. attempt number :\n"+(attempt++));
				Thread.sleep(2000);
			}
			else{
				Logger.writeLog(FIControlelogfile,"index is ok. it is responding to the heartbeat\n");
				return true;
			}
		}
	}
	
	public boolean readFINodes() throws IOException{//reads the configuration file
		Logger.writeLog(FIControlelogfile,"reading fi_nodes.xml file\n");//and assign the values to the class variables
		try {//like ip addresses, user names and ports
			
			String name;
			File fXmlFile = new File("C:\\test\\frontier\\dom\\master-nodes.xml");
			DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
			Document doc = dBuilder.parse(fXmlFile);
		        doc.getDocumentElement().normalize();
		        
		        NodeList nList = doc.getElementsByTagName("node");
		        for (int temp = 0; temp < nList.getLength(); temp++) {
		        	Node nNode = nList.item(temp);
		                if (nNode.getNodeType() == Node.ELEMENT_NODE) {
		                        Element eElement = (Element) nNode;
		 			
					name = eElement.getElementsByTagName("name").item(0).getTextContent();
					
					
					
				    if(name.equals("frontier")){
				    	frontier_ip =  eElement.getElementsByTagName("ip").item(0).getTextContent();
				    	frontier_user = eElement.getElementsByTagName("user").item(0).getTextContent();
				    	frontier_port = Integer.parseInt(eElement.getElementsByTagName("port").item(0).getTextContent());
				    }
				    else{
				    	index_ip = eElement.getElementsByTagName("ip").item(0).getTextContent();
				    	index_user = eElement.getElementsByTagName("user").item(0).getTextContent();
				    	index_port = Integer.parseInt(eElement.getElementsByTagName("port").item(0).getTextContent());
				    }
				}
			}
		    Logger.writeLog(FIControlelogfile,"reading of fi_nodes.xml file is over\n");
            Logger.writeLog(FIControlelogfile,"index_ip"+index_ip+"\nfrontier_ip"+frontier_ip+"\n");
            Logger.writeLog(FIControlelogfile,"index_user"+index_user+"\nfrontier_user"+frontier_user+"\n"); 
            //System.out.println("index_ip"+index_ip+"\nfrontier_ip"+frontier_ip);
		    //System.out.println("index_user"+index_user+"\nfrontier_user"+frontier_user);
            return true;
        }
		catch (SAXParseException err) {
			Logger.writeLog(FIControlelogfile,"following error occured while reading fi_nodes.xml file\n");
			Logger.writeLog(FIControlelogfile,"** Parsing error" + ", line " 
				    + err.getLineNumber () + ", uri " + err.getSystemId ()+"\n");
			//System.out.println ("** Parsing error" + ", line " 
		    //+ err.getLineNumber () + ", uri " + err.getSystemId ());
			Logger.writeLog(FIControlelogfile," " + err.getMessage ()+"\n");
		    //System.out.println(" " + err.getMessage ());
			return false;
        }
		catch (SAXException e) {
			Logger.writeLog(FIControlelogfile,"following error occured while reading fi_nodes.xml file\n");
			Logger.writeLog(FIControlelogfile, "SAXException :"+e+"\n");
			Exception x = e.getException ();
		    ((x == null) ? e : x).printStackTrace ();
		    return false;
        }
		catch (Throwable t) {
			Logger.writeLog(FIControlelogfile,"following error occured while reading fi_nodes.xml file\n");
			Logger.writeLog(FIControlelogfile, "Throwable exception :"+t+"\n");
			//Logger.writeLog(FIControlelogfile,t.printStackTrace());
			return false;
		}
		//System.exit (0);
	}
	
	public boolean ping(String name) throws IOException{//return true if ping is successful
		Logger.writeLog(FIControlelogfile,"pinging of "+name+" node started\n");
		String host="";
		if(name.equals("index")){
			host = index_ip;
		}
		else{
			host = frontier_ip;
		}
		int timeout = 3000;
		try{
			boolean status = InetAddress.getByName(host).isReachable(timeout);
			Logger.writeLog(FIControlelogfile,"pinging of "+name+" node is done\n");
			if(!status){
				Logger.writeLog(FIControlelogfile,"following error occured during pinging of "+name+" node\n");
				Logger.writeLog(FIControlelogfile,name+" node Host can't be pinged (node is not started) \n");
			}
			return status;
		}
		catch(UnknownHostException e){
			Logger.writeLog(FIControlelogfile,"following error occured during pinging of "+name+" node\n");
			Logger.writeLog(FIControlelogfile,name+" node Host does not exists \n");
			//System.err.println("Host does not exists \n check log record for futher details");
			//exit(0);
		}
		catch(Exception e){
			Logger.writeLog(FIControlelogfile,"following error occured during pinging of "+name+" node\n");
			Logger.writeLog(FIControlelogfile,name+" node pinging exception :"+e+"\n");
		}	
		return false;
	}
			
	public void startNode(String nodename) throws IOException{
		Logger.writeLog(FIControlelogfile,"Starting of "+nodename+" is started\n");
		String cmd;
		if(nodename.equals("frontier")){//creating a remote ssh command
			cmd= "ssh "+frontier_user+"@"+frontier_ip+" ~/wsc/bin/start_frontier.sh\n";
		}
		else{
			cmd= "ssh "+index_user+"@"+index_ip+" ~/wsc/bin/start_index.sh\n";
		}
		try{
			Process p = Runtime.getRuntime().exec(cmd);
			p.waitFor();
			 
			BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
			Logger.writeLog(FIControlelogfile,"following is the out put during the start up of "+nodename+"\n");
			while(r.ready()){
				Logger.writeLog(FIControlelogfile,r.readLine()+"\n");
			} 
			Logger.writeLog(FIControlelogfile,"Starting of "+nodename+" is done\n");
		}
		catch(Throwable t){
			Logger.writeLog(FIControlelogfile,"following exception occured during the starting of "+nodename+"\n");
			Logger.writeLog(FIControlelogfile,"throwable exception is :"+t+"\n");
		}
			
	}
}
